home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sunrpc / rpc_prot.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  7KB  |  290 lines

  1. /* @(#)rpc_prot.c    2.3 88/08/07 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #if !defined(lint) && defined(SCCSIDS)
  31. static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
  32. #endif
  33.  
  34. /*
  35.  * rpc_prot.c
  36.  *
  37.  * Copyright (C) 1984, Sun Microsystems, Inc.
  38.  *
  39.  * This set of routines implements the rpc message definition,
  40.  * its serializer and some common rpc utility routines.
  41.  * The routines are meant for various implementations of rpc -
  42.  * they are NOT for the rpc client or rpc service implementations!
  43.  * Because authentication stuff is easy and is part of rpc, the opaque
  44.  * routines are also in this program.
  45.  */
  46.  
  47. #include <sys/param.h>
  48.  
  49. #include <rpc/rpc.h>
  50.  
  51. /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
  52.  
  53. struct opaque_auth _null_auth;
  54.  
  55. /*
  56.  * XDR an opaque authentication struct
  57.  * (see auth.h)
  58.  */
  59. bool_t
  60. xdr_opaque_auth(xdrs, ap)
  61.     register XDR *xdrs;
  62.     register struct opaque_auth *ap;
  63. {
  64.  
  65.     if (xdr_enum(xdrs, &(ap->oa_flavor)))
  66.         return (xdr_bytes(xdrs, &ap->oa_base,
  67.             &ap->oa_length, MAX_AUTH_BYTES));
  68.     return (FALSE);
  69. }
  70.  
  71. /*
  72.  * XDR a DES block
  73.  */
  74. bool_t
  75. xdr_des_block(xdrs, blkp)
  76.     register XDR *xdrs;
  77.     register des_block *blkp;
  78. {
  79.     return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
  80. }
  81.  
  82. /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
  83.  
  84. /*
  85.  * XDR the MSG_ACCEPTED part of a reply message union
  86.  */
  87. bool_t 
  88. xdr_accepted_reply(xdrs, ar)
  89.     register XDR *xdrs;   
  90.     register struct accepted_reply *ar;
  91. {
  92.  
  93.     /* personalized union, rather than calling xdr_union */
  94.     if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
  95.         return (FALSE);
  96.     if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
  97.         return (FALSE);
  98.     switch (ar->ar_stat) {
  99.  
  100.     case SUCCESS:
  101.         return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
  102.  
  103.     case PROG_MISMATCH:
  104.         if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  105.             return (FALSE);
  106.         return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  107.     }
  108.     return (TRUE);  /* TRUE => open ended set of problems */
  109. }
  110.  
  111. /*
  112.  * XDR the MSG_DENIED part of a reply message union
  113.  */
  114. bool_t 
  115. xdr_rejected_reply(xdrs, rr)
  116.     register XDR *xdrs;
  117.     register struct rejected_reply *rr;
  118. {
  119.  
  120.     /* personalized union, rather than calling xdr_union */
  121.     if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
  122.         return (FALSE);
  123.     switch (rr->rj_stat) {
  124.  
  125.     case RPC_MISMATCH:
  126.         if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
  127.             return (FALSE);
  128.         return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
  129.  
  130.     case AUTH_ERROR:
  131.         return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
  132.     }
  133.     return (FALSE);
  134. }
  135.  
  136. static struct xdr_discrim reply_dscrm[3] = {
  137.     { (int)MSG_ACCEPTED, xdr_accepted_reply },
  138.     { (int)MSG_DENIED, xdr_rejected_reply },
  139.     { __dontcare__, NULL_xdrproc_t } };
  140.  
  141. /*
  142.  * XDR a reply message
  143.  */
  144. bool_t
  145. xdr_replymsg(xdrs, rmsg)
  146.     register XDR *xdrs;
  147.     register struct rpc_msg *rmsg;
  148. {
  149.     if (
  150.         xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
  151.         xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
  152.         (rmsg->rm_direction == REPLY) )
  153.         return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
  154.            (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
  155.     return (FALSE);
  156. }
  157.  
  158.  
  159. /*
  160.  * Serializes the "static part" of a call message header.
  161.  * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
  162.  * The rm_xid is not really static, but the user can easily munge on the fly.
  163.  */
  164. bool_t
  165. xdr_callhdr(xdrs, cmsg)
  166.     register XDR *xdrs;
  167.     register struct rpc_msg *cmsg;
  168. {
  169.  
  170.     cmsg->rm_direction = CALL;
  171.     cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  172.     if (
  173.         (xdrs->x_op == XDR_ENCODE) &&
  174.         xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  175.         xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  176.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  177.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
  178.         return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
  179.     return (FALSE);
  180. }
  181.  
  182. /* ************************** Client utility routine ************* */
  183.  
  184. static void
  185. accepted(acpt_stat, error)
  186.     register enum accept_stat acpt_stat;
  187.     register struct rpc_err *error;
  188. {
  189.  
  190.     switch (acpt_stat) {
  191.  
  192.     case PROG_UNAVAIL:
  193.         error->re_status = RPC_PROGUNAVAIL;
  194.         return;
  195.  
  196.     case PROG_MISMATCH:
  197.         error->re_status = RPC_PROGVERSMISMATCH;
  198.         return;
  199.  
  200.     case PROC_UNAVAIL:
  201.         error->re_status = RPC_PROCUNAVAIL;
  202.         return;
  203.  
  204.     case GARBAGE_ARGS:
  205.         error->re_status = RPC_CANTDECODEARGS;
  206.         return;
  207.  
  208.     case SYSTEM_ERR:
  209.         error->re_status = RPC_SYSTEMERROR;
  210.         return;
  211.  
  212.     case SUCCESS:
  213.         error->re_status = RPC_SUCCESS;
  214.         return;
  215.     }
  216.     /* something's wrong, but we don't know what ... */
  217.     error->re_status = RPC_FAILED;
  218.     error->re_lb.s1 = (long)MSG_ACCEPTED;
  219.     error->re_lb.s2 = (long)acpt_stat;
  220. }
  221.  
  222. static void 
  223. rejected(rjct_stat, error)
  224.     register enum reject_stat rjct_stat;
  225.     register struct rpc_err *error;
  226. {
  227.  
  228.     switch (rjct_stat) {
  229.  
  230.     case RPC_VERSMISMATCH:
  231.         error->re_status = RPC_VERSMISMATCH;
  232.         return;
  233.  
  234.     case AUTH_ERROR:
  235.         error->re_status = RPC_AUTHERROR;
  236.         return;
  237.     }
  238.     /* something's wrong, but we don't know what ... */
  239.     error->re_status = RPC_FAILED;
  240.     error->re_lb.s1 = (long)MSG_DENIED;
  241.     error->re_lb.s2 = (long)rjct_stat;
  242. }
  243.  
  244. /*
  245.  * given a reply message, fills in the error
  246.  */
  247. void
  248. _seterr_reply(msg, error)
  249.     register struct rpc_msg *msg;
  250.     register struct rpc_err *error;
  251. {
  252.  
  253.     /* optimized for normal, SUCCESSful case */
  254.     switch (msg->rm_reply.rp_stat) {
  255.  
  256.     case MSG_ACCEPTED:
  257.         if (msg->acpted_rply.ar_stat == SUCCESS) {
  258.             error->re_status = RPC_SUCCESS;
  259.             return;
  260.         };
  261.         accepted(msg->acpted_rply.ar_stat, error);
  262.         break;
  263.  
  264.     case MSG_DENIED:
  265.         rejected(msg->rjcted_rply.rj_stat, error);
  266.         break;
  267.  
  268.     default:
  269.         error->re_status = RPC_FAILED;
  270.         error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
  271.         break;
  272.     }
  273.     switch (error->re_status) {
  274.  
  275.     case RPC_VERSMISMATCH:
  276.         error->re_vers.low = msg->rjcted_rply.rj_vers.low;
  277.         error->re_vers.high = msg->rjcted_rply.rj_vers.high;
  278.         break;
  279.  
  280.     case RPC_AUTHERROR:
  281.         error->re_why = msg->rjcted_rply.rj_why;
  282.         break;
  283.  
  284.     case RPC_PROGVERSMISMATCH:
  285.         error->re_vers.low = msg->acpted_rply.ar_vers.low;
  286.         error->re_vers.high = msg->acpted_rply.ar_vers.high;
  287.         break;
  288.     }
  289. }
  290.